/*
 file: function.js
 dependsOn: core.js
 */

$.addMethods(Function, 
{  
  /**
   * Sets this function up for execution after the delay specified (in ms)
   * @alias Function.prototype.delay
   * @param {Number} delay The number of ms in the future to schedule 
   *  execution for. All remaining arguments are passed to the function when
   *  it is executed.
   * @return The timer, which can be passed to $.cancel before
   *  the delay has elapsed to cancel the scheduled execution.
   * @since 0.1
   */
  delay: function() 
  { 
    var self    = this, 
        args    = $.A(arguments), 
        timeout = args.shift();
         
    return setTimeout(function() {
      return self.apply(self, args);
    }, timeout);
  },
  
  /**
   * Defers the execution of this function for 10 ms. This is the same as
   * calling delay with 10 as the first argument and is simply provided
   * as a convenience.
   * @alias Function.prototype.defer
   * @param {Object} [args] Zero or more arguments to pass to the deferred 
   *  function
   * @return The timer, which can be passed to $.cancel within 10 ms to 
   *  cancel the scheduled execution.
   * @since 0.1
   */
  defer: function() {
    var self = this;
    
    return setTimeout(function() {
      return self.apply(self, arguments);
    }, 10);
  },
  
  wrap: function(wrapper) {
    var self = this;
    
    return function() {
      return wrapper.apply(this, [self.bind(this)].concat($A(arguments)));
    }
  }
});
